#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <string.h>


int main(void){
  // 申请共享内存，关联文件描述符
  char shm_file[100];
  sprintf(shm_file,"/share%d",getpid());
  int fd = shm_open(shm_file,O_CREAT|O_RDWR,0644);
  if(fd<0){
    perror("shm_open");
    exit(EXIT_FAILURE);
  }
  // 扩充内存区域
  if(ftruncate(fd,100)<0){
    perror("ftruncate");
    exit(EXIT_FAILURE);
  }
  // 进行内存地址的映射
  char *share_addr = mmap(NULL,100,PROT_READ|PROT_WRITE,MAP_SHARED,fd,0);
  if(share_addr==MAP_FAILED){
    perror("mmap");
    exit(EXIT_FAILURE);
  }
  close(fd); // 关闭对应的文件描述符
  pid_t son_pid = fork();
  if(son_pid<0){
    perror("fork");
    exit(EXIT_FAILURE);
  }
  if(son_pid==0){ // 子进程写
    sprintf(share_addr,"子进程%d到此一游",getpid());
    printf("子进程%d写入数据到共享内存:%s\n",
      getpid(),share_addr);
  }else{ // 父进程读
    sleep(1); // 休眠1秒，确保子进程先写入成功
    printf("父进程%d从共享内存读取子进程%d写的数据:%s\n",
    getpid(),son_pid,share_addr);
    wait(NULL); // 等待子进程结束
    sleep(10); // 睡眠10秒，以便观查共享内存关联的临时文件
    // 释放映射区域
    if(munmap(share_addr,100)<0){
      perror("munmap");
      exit(EXIT_FAILURE);
    }
    // 删除共享内存
    if(shm_unlink(shm_file)<0){
      perror("shm_unlink");
      exit(EXIT_FAILURE);
    }
  }
  return 0;
}
